/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
 * Generated on : 2022/7/26
 * Function description: Header file for implementing the board-level
 * configuration mechanism of the PCIe module
 */
#ifndef PCIE_BOARD_ATTR_H
#define PCIE_BOARD_ATTR_H

#include "hw_drv_core.h"

#define WIFI0_CHIP_TYPE WIFI_CHIP_TYPE
#define PCIE0_ACP_SWITCH PCIE_ACP_SWITCH

/*
 * ini file cfg index
 */
enum pcie_init_cfg_index {
	/* Common attr */
	PCIE_CHANNEL_CROSS = 0, /* 00: channel crossover */
	PCIE_CHANNEL_SELECT,    /* 01: channel select */
	/* channel attr */
	PCIE0_RESET_GPIO,       /* 02: pcie0 reset gpio */
	PCIE1_RESET_GPIO,       /* 03: pcie1 reset gpio */
	PCIE2_RESET_GPIO,       /* 04: pcie2 reset gpio */
	WIFI0_RESET_GPIO,       /* 05: wifi0 reset gpio */
	WIFI1_RESET_GPIO,       /* 06: wifi1 reset gpio */
	WIFI2_RESET_GPIO,       /* 07: wifi2 reset gpio */
	/*
	 * 08: wifi0 chip type
	 * if wifi1 chip type invalid, use wifi0 chip type
	 */
	WIFI_CHIP_TYPE,
	WIFI1_CHIP_TYPE,        /* 09: wifi1 chip type */
	WIFI2_CHIP_TYPE,        /* 10: wifi2 chip type */
	PCIE0_IRQ_MODE,         /* 11: pcie0 interrupt type */
	PCIE1_IRQ_MODE,         /* 12: pcie1 interrupt type */
	PCIE2_IRQ_MODE,         /* 13: pcie2 interrupt type */
	PCIE0_VOLTAGE_SWING,    /* 14: pcie0 differential signal swing(voltage) */
	PCIE1_VOLTAGE_SWING,    /* 15: pcie1 differential signal swing(voltage) */
	PCIE2_VOLTAGE_SWING,    /* 16: pcie2 differential signal swing(voltage) */
	PCIE0_DRV_ABILITY,      /* 17: pcie0 differential signal drv ability(current) */
	PCIE1_DRV_ABILITY,      /* 18: pcie1 differential signal drv ability(current) */
	PCIE2_DRV_ABILITY,      /* 19: pcie2 differential signal drv ability(current) */
	PCIE_ACP_SWITCH,        /* 20: pcie0 ACP enable cfg */
	PCIE1_ACP_SWITCH,       /* 21: pcie1 ACP enable cfg */
	PCIE2_ACP_SWITCH,       /* 22: pcie2 ACP enable cfg */
	PCIE0_MSI_ENHANCE,      /* 23: pcie0 msi interrupt affinity enhancemen */
	PCIE1_MSI_ENHANCE,      /* 24: pcie1 msi interrupt affinity enhancemen */
	PCIE2_MSI_ENHANCE,      /* 25: pcie2 msi interrupt affinity enhancemen */
	PCIE_LANE_INIT_MODE,    /* 26: pcie lane init mode select */
	/* QCN attr */
	QCA_WIFI0_ENABLE_GPIO,  /* 27: QCN wifi 5G FEM power control */
	QCA_WIFI1_ENABLE_GPIO,  /* 28: QCN wifi 5G FEM power control */
	QCA_WIFI2_ENABLE_GPIO,  /* 29: QCN wifi 5G FEM power control */
	QCA_WIFI0_RESET_GPIO,   /* 30: QCN wifi0 reset gpio */
	QCA_WIFI1_RESET_GPIO,   /* 31: QCN wifi1 reset gpio */
	QCA_WIFI2_RESET_GPIO,   /* 32: QCN wifi2 reset gpio */
	/* DY attr */
	EXT_RF0_POWER_GPIO,     /* 33: DY wifi0 radio frequency power control gpio */
	EXT_RF1_POWER_GPIO,     /* 34: DY wifi1 radio frequency power control gpio */
	/* DFX attr */
	DFX_PCIE_VOLTAGE_AMP,   /* 35: DFX pcie voltage cfg */
	SSD_PCIE_CHANNEL,       /* 36: ssd attr */
	PCIE_SPEED,             /* 37: pcie speed */
	PCIE_TIME,              /* 38: pcie link set up retry times */
	WIFI_CHIP_3V3_PWR,      /* 39: wifi 3.3V power control gpio */

	PCIE_INI_CONFIG_MAX
};

/* peer wifi and lsw chip type */
enum pcie_slave_chip_type {
	WIFI_CHIP_TYPE_COMMON = 0,   /* general cfg */
	WIFI_CHIP_TYPE_BRIDGE,       /* bridge cfg */
	WIFI_CHIP_TYPE_1151,         /* SD1151 */
	WIFI_CHIP_TYPE_1152,         /* SD1152 noneutectic oscillator */
	WIFI_CHIP_TYPE_1152_CRYSTAL, /* SD1152 eutectic oscillation */
	WIFI_CHIP_TYPE_QCA,          /* qualcomm wifi */
	WIFI_CHIP_TYPE_MXL,          /* mering wifi */
	WIFI_CHIP_TYPE_CELENO,       /* Celeno wifi */
	WIFI_CHIP_TYPE_1153,         /* SD1153 */

	/* To differentiate Wi-Fi and LSW, 0xfffff space is reserved for Wi-Fi
	 * LSW starts from high 16 bits 0x10000. */
	/* RTL931X */
	EXTLSW_CHIP_TYPE_RTL931X = 0x10000,
	/* LSW2125 */
	EXTLSW_CHIP_TYPE_LSW2125,

	PCIE_SLAVE_CHIP_TYPE_BUTT
};

/* pcie controller num */
enum pcie_ctrl_index {
	PCIE_INDEX_0 = 0, /* pcie 0 */
	PCIE_INDEX_1,     /* pcie 1 */
	PCIE_INDEX_2,     /* pcie 2 */

	PCIE_INDEX_MAX
};

/* is support pcie msi enhance */
enum pcie_msi_enhance_en {
	PCIE_MSI_ENHANCE_DIS = 0,
	PCIE_MSI_ENHANCE_EN,

	PCIE_MSI_ENHANCE_BUTT,
};

/* PCIE lanes attr cfg */
struct pcie_channel_attr {
	uint8_t pcie_reset_gpio;     /* pcie reset control gpio */
	uint8_t wifi_reset_gpio;     /* wifi reset control gpio */
	uint8_t pcie_drv_ability;    /* pcie drv ability cfg */
	uint8_t pcie_acp_close;      /* pcie acp cfg, 1-close, 0-open, 0xff-default open */
	uint32_t wifi_chip_type;     /* wifi chip type, wifi_chip_type */
	/*
	 * interrupt mode select
	 * default INTx for old devices compatible
	 */
	uint32_t interrupt_mode;
	uint32_t pcie_voltage_swing; /* pcie swing cfg */
	uint32_t pcie_msi_enhance;   /* open pcie msi enhance, support subinterrupt binding cores */
};

/* qualcomm QCN wifi special sttr */
struct qca_wifi_chip_attr {
	uint8_t wifi_qca_enable_gpio; /* qualcomm WiFi and 5G FEM power enable signal
				       * high level enable output
				       */
	uint8_t qca_wifi_reset_gpio;  /* qualcomm WiFi reset gpio */
};

/* DY wifi special sttr */
struct dy_wifi_chip_attr {
	uint8_t ext_rf_power_gpio;    /* wifi ex RF module power gpio */
};

/* PCIE extend cfg */
struct pcie_board_ini_attr {
	/*
	 * general cfg
	 * 1. general cfg not for specific wifi chip
	 * 2. add new cfg, consider whether PCIE0, PCIE1 ... PCIEn need to
	 *    be configured separately now and in future, if need, there
	 *    should be pcie index to support separate PCIE cfg
	 */
	/* pcie control channel enable,bit0: pcie0, bit1:pcie1 */
	uint32_t pcie_channel_select;
	/* pcie control channel cross, 1-cross, 0-not cross, 0xff-default not cross */
	uint8_t pcie_channel_cross;
	/* channel attr cfg */
	struct pcie_channel_attr chan_attr[PCIE_INDEX_MAX];
	uint32_t pcie_lane_init_mode;

	/* different wifi chip need separate cfg */
	struct qca_wifi_chip_attr qca_wifi_attr[PCIE_INDEX_MAX]; /* QCN wifi special attr */
	struct dy_wifi_chip_attr dy_wifi_attr[PCIE_INDEX_MAX];   /* DY wifi special attr */

	/* DFX ability cfg */
	uint32_t dfx_pcie_voltage_amp;    /* DFX pcie swing and pre-emphasis */
	uint32_t ssd_pcie_channel;        /* ssd channel */
	uint32_t pcie_speed;              /* pcie speed */
	uint32_t pcie_time;               /* pcie time */
	uint32_t wifi_3v3_pwr;            /* wifi 3.3V power contrl */
};

/* 1152 chip control gpio */
struct wifi_hi1152_cfg {
	uint8_t pcie_rst_gpio;         /* PCIE reset gpio */
	uint8_t wl_en_gpio;            /* WL_EN enable control gpio */
	uint8_t pmu_pwren_gpio;        /* wifi chip power control gpio */
	uint8_t ctl_0v9_gpio;          /* wifi core voltage(0.9V) control */
};

/* 1153 chip control gpio */
struct wifi_dy1153_cfg {
	uint8_t pcie0_reset_gpio;      /* PCIE0 reset gpio */
	uint8_t ext_rf0_power_gpio;    /* ex RF0 module power gpio */
	uint8_t wifi0_power_gpio;      /* wifi0 chip power control gpio */
	uint8_t pcie1_reset_gpio;      /* PCIE1 reset gpio */
	uint8_t ext_rf1_power_gpio;    /* ex RF1 module power gpio */
	uint8_t wifi1_power_gpio;      /* wifi1 chip power control gpio */
	uint8_t wifi_3v3_power_gpio;   /* wifi 3.3V power contrl gpio */
	uint8_t reserv[1];             /* reserve */
};

/* MXL chip control gpio */
struct wifi_mxl_cfg {
	uint8_t wifi_reset_gpio;       /* wifi chip reset gpio */
	uint8_t ctl_0v9_gpio;          /* wificore voltage(0.9V) control */
};

union soc_dfx_ctrl {
	uint32_t value;
	struct {
		uint32_t safetycode_ctrl : 2; /* safetycode print control */
		uint32_t startcode_ctrl : 2;  /* startcode print control */
		uint32_t uboot_ctrl : 2;      /* uboot print control */
		uint32_t kernel_ctrl : 2;     /* kernel print control */
		uint32_t rst_reason : 2;      /* indicates whether a hard power failure occurs */
		uint32_t cpu_core : 2;        /* cpu core counts */
		uint32_t ddr_freq : 4;        /* ddr frequency */
		/* 1 indicates that the value of the software register (0x10100C0C) is used */
		uint32_t cpu_freq_set : 1;    /* flag bit for CPU frequency */
		uint32_t ddr_freq_set : 1;    /* DDR frequency cfg */
		uint32_t pcie_swing_set : 1;  /* PCIE swing */

		uint32_t reserved : 13;       /* reserve 13 bits */
	} bits;
};

/* get board-level cfg of wifi chip */
int32_t pcie_board_parse_ini_cfg(void);
void pcie_get_1152_board_attr(struct wifi_hi1152_cfg *wifi_1152_cfg);
void pcie_get_mxl_board_attr(struct wifi_mxl_cfg *wifi_mxl_cfg);
void pcie_get_dy1153_board_attr(struct wifi_dy1153_cfg *wifi_dy1153_cfg);
void pcie_get_board_attr(struct pcie_board_ini_attr **pcie_board_attr);
void pcie_board_get_wifi_chip_board_attr(void);

/* whether wifi chip type */
bool pcie_is_extlsw_chip(uint32_t pcie_index);
bool pcie_is_wifi_mxl_chip(uint32_t pcie_index);
bool pcie_is_wifi_cel_chip(uint32_t pcie_index);
bool pcie_is_wifi1152_chip(uint32_t pcie_index);
bool pcie_is_wifi1153_chip(uint32_t pcie_index);
bool pcie_is_wifi115x_chip(uint32_t pcie_index);
bool pcie_is_wifi_qca_chip(uint32_t pcie_index);
bool pcie_is_extlsw_type2125(uint32_t pcie_index);

/* get interrupt type */
uint32_t pcie_get_interrupt_mode(uint32_t pcie_index);

/* support feature */
bool pcie_is_support_msi_enhance(uint32_t pcie_index);

#endif /* PCIE_BOARD_ATTR_H */
